﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Globalization;

namespace D3crft.Characters {
    public class ocCharacterManager {

        public delegate void delCharacterLoadingProcessHandler(int iTotalCharCount, int iCurrentCharCount, string sFilename);

        public event delCharacterLoadingProcessHandler evCharacterLoadingProcess_Started;
        public event delCharacterLoadingProcessHandler evCharacterLoadingProcess_PreloadUpdate;
        public event delCharacterLoadingProcessHandler evCharacterLoadingProcess_PostloadUpdate;
        public event delCharacterLoadingProcessHandler evCharacterLoadingProcess_Finished;

        List<ClassObjects.ocCharacter> lCharacters = new List<ClassObjects.ocCharacter>();

        string sCharacterPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6) + "\\characters";

        // ####################################################
        // #####    Object Initialization
        // ####################################################
        #region Object Initialization

        public ocCharacterManager() {
            do_Initialize();
            do_Preset();
            do_Startup();
        }

        ~ocCharacterManager() {
            do_Finalize();
        }

        private void do_Initialize() {

        }

        private void do_Preset() {
            evCharacterLoadingProcess_Started += new delCharacterLoadingProcessHandler(ev_Object_CharacterLoadingProcess_Started);
            evCharacterLoadingProcess_PreloadUpdate += new delCharacterLoadingProcessHandler(ev_Object_CharacterLoadingProcess_PreloadUpdate);
            evCharacterLoadingProcess_PostloadUpdate += new delCharacterLoadingProcessHandler(ev_Object_CharacterLoadingProcess_PostloadUpdate);
            evCharacterLoadingProcess_Finished += new delCharacterLoadingProcessHandler(ev_Object_CharacterLoadingProcess_Finished);
        }

        private void do_Startup() {

        }

        private void do_Finalize() {

        }

        #endregion

        // ####################################################
        // #####    Public Access
        // ####################################################
        #region Public Access

        public void SetCharacterPath(string sPath) {
            sCharacterPath = sPath;
        }

        public int ReloadCharacters() {
            return do_LoadCharacters(sCharacterPath);
        }

        public bool IsNameClassCombinationUnique(string sName, ClassObjects.ocCharacter.eCharacterClass eClass) {
            for (int i = 0; i < lCharacters.Count; i++) {
                if (lCharacters[i].sName == sName) {
                    if (lCharacters[i].eClass == eClass) {
                        return false;
                    }
                }
            }
            return true;
        }

        public bool CheckFreeID() {
            if (get_FreeCharacterID() != null) {
                return true;
            }
            return false;
        }

        public bool AddNewCharacter(ClassObjects.ocCharacter oCharacter) {
            string sTemp;

            if (oCharacter != null) {
                sTemp = get_FreeCharacterID();
                if (sTemp != null) {
                    oCharacter.sID = sTemp;
                    lCharacters.Add(oCharacter);
                    do_SaveCharacter(sCharacterPath, oCharacter);
                    return true;
                }
            }
            return false;
        }

        public bool EditCharacter(string sID, ClassObjects.ocCharacter oCharacter) {
            if (sID == oCharacter.sID) {
                if (get_IsIDInUse(sID)) {
                    if (do_DeleteCharacterByID(sID)) {
                        lCharacters.Add(oCharacter);
                        do_SaveCharacter(sCharacterPath, oCharacter);
                        return true;
                    }

                }
            }
            return false;
        }

        public bool RemoveCharacter(string sID) {
            if (get_IsIDInUse(sID)) {
                return do_DeleteCharacterByID(sID);
            }
            return false;
        }

        public List<ClassObjects.ocCharacter> GetCharacterList() {
            return lCharacters;
        }

        public ClassObjects.ocCharacter GetCharacter(string sID) {
            return get_CharacterByID(sID);
        }

        #endregion

        // ####################################################
        // #####    Private Functions
        // ####################################################
        #region Private Functions

        private string get_FreeCharacterID() {
            for (int i = 1001; i < 2000; i++) {
                if (!get_IsIDInUse(i.ToString())) {
                    return i.ToString();
                }
            }
            return null;
        }

        private bool get_IsIDInUse(string sID) {
            for (int i = 0; i < lCharacters.Count; i++) {
                if (lCharacters[i].sID == sID) { return true; }
            }
            return false;
        }

        private ClassObjects.ocCharacter get_CharacterByID(string sID) {
            for (int i = 0; i < lCharacters.Count; i++) {
                if (lCharacters[i].sID == sID) {
                    return lCharacters[i];
                }
            }
            return null;
        }

        private bool do_DeleteCharacterByID(string sID) {
            FileInfo oFInfo;
            string sFile;

            for (int i = 0; i < lCharacters.Count; i++) {
                if (lCharacters[i].sID == sID) {
                    sFile = sCharacterPath + "\\" + lCharacters[i].sName + ".xml";
                    oFInfo = new FileInfo(sFile);
                    if (oFInfo.Exists) { oFInfo.Delete(); }
                    lCharacters.RemoveAt(i);
                    return true;
                }
            }
            return false;
        }

        private int do_LoadCharacters(string sPath) {
            ClassObjects.ocCharacter oCharacter = null;
            XmlTextReader oReader;
            XmlDocument oDoc;
            XmlNode oNode_Character;
            XmlNodeList oNodes_Childs;
            XmlAttributeCollection oAttributes;
            DirectoryInfo oCharsDirectory = new DirectoryInfo(sPath);
            string sTemp = "";
            int iTotalCharCount = 0;


            if (!oCharsDirectory.Exists) {
                return 0;
            }

            string[] sFiles = Directory.GetFiles(sPath);
            string sError = "";
            bool bTemp;
            int iLoadCount = 0;

            for (int i = 0; i <= sFiles.GetUpperBound(0); i++) {
                if (sFiles[i].EndsWith(".xml")) {
                    iTotalCharCount++;
                }
            }
            evCharacterLoadingProcess_Started(iTotalCharCount, 0, "character(s)");

            for (int i = 0; i <= sFiles.GetUpperBound(0); i++) {
                if (sFiles[i].EndsWith(".xml")) {
                    evCharacterLoadingProcess_PreloadUpdate(iTotalCharCount, iLoadCount + 1, sFiles[i]);
                    // load file
                    oReader = new XmlTextReader(sFiles[i]);
                    oReader.Read();
                    oDoc = new XmlDocument();
                    oDoc.Load(oReader);

                    oNode_Character = oDoc.GetElementsByTagName("Character")[0];
                    oNodes_Childs = oNode_Character.ChildNodes;

                    // Character Node
                    bTemp = true;
                    oAttributes = oNode_Character.Attributes;
                    for (int j = 0; j < oAttributes.Count && bTemp; j++) {
                        switch (oAttributes[j].Name) {
                            case "Name":
                                sTemp = oAttributes[j].Value;
                                break;
                            case "Class":
                                switch (ClassObjects.ocCharacter.GetClassEnumeration(oAttributes[j].Value)) {
                                    case ClassObjects.ocCharacter.eCharacterClass.Barbarian:
                                        oCharacter = new ClassObjects.ocBarbarian();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Barbarian;
                                        break;
                                    case ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter:
                                        oCharacter = new ClassObjects.ocDemonHunter();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter;
                                        break;
                                    case ClassObjects.ocCharacter.eCharacterClass.Crusader:
                                        oCharacter = new ClassObjects.ocCrusader();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Crusader;
                                        break;
                                    case ClassObjects.ocCharacter.eCharacterClass.Monk:
                                        oCharacter = new ClassObjects.ocMonk();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Monk;
                                        break;
                                    case ClassObjects.ocCharacter.eCharacterClass.Wizard:
                                        oCharacter = new ClassObjects.ocWizard();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Wizard;
                                        break;
                                    case ClassObjects.ocCharacter.eCharacterClass.Witch_Doctor:
                                        oCharacter = new ClassObjects.ocWitchDoctor();
                                        oCharacter.eClass = ClassObjects.ocCharacter.eCharacterClass.Witch_Doctor;
                                        break;
                                    default:
                                        oCharacter = new ClassObjects.ocCharacter();
                                        bTemp = false;
                                        sError = "Class: " + oAttributes[j].Value;
                                        break;
                                }
                                oCharacter.sName = sTemp;
                                break;
                            default:

                                break;
                        }
                    }
                    if (bTemp) {
                        oNodes_Childs = oNode_Character.ChildNodes;
                        for (int j = 0; j < oNodes_Childs.Count; j++) {
                            switch (oNodes_Childs[j].Name) {
                                case "BaseStats":
                                    oAttributes = oNodes_Childs[j].Attributes;
                                    for (int k = 0; k < oAttributes.Count; k++) {
                                        switch (oAttributes[k].Name) {
                                            case "Strength":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iBaseStat_Strength);
                                                break;
                                            case "Dexterity":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iBaseStat_Dexterity);
                                                break;
                                            case "Intelligence":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iBaseStat_Intelligence);
                                                break;
                                            case "Vitality":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iBaseStat_Vitality);
                                                break;
                                            default:
                                                bTemp = false;
                                                sError = "BaseStats: " + oAttributes[k].Name;
                                                break;
                                        }
                                    }
                                    break;
                                case "OffensiveStats":
                                    oAttributes = oNodes_Childs[j].Attributes;
                                    for (int k = 0; k < oAttributes.Count; k++) {
                                        switch (oAttributes[k].Name) {
                                            case "AttackSpeedIncrease":
                                                oCharacter.fOffStat_AttackSpeedInrease = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "CritChance":
                                                oCharacter.fOffStat_CritChance = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "CritDamage":
                                                oCharacter.fOffStat_CritDamage = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "BonusDamageMin":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iOffStat_BonusDamage_Min);
                                                break;
                                            case "BonusDamageMax":
                                                int.TryParse(oAttributes[k].Value, out oCharacter.iOffStat_BonusDamage_Max);
                                                break;
                                            default:
                                                bTemp = false;
                                                sError = "OffensiveStats: " + oAttributes[k].Name;
                                                break;
                                        }
                                    }
                                    break;
                                case "WeaponStats":
                                    oAttributes = oNodes_Childs[j].Attributes;
                                    for (int k = 0; k < oAttributes.Count; k++) {
                                        switch (oAttributes[k].Name) {
                                            case "MHDPS":
                                                oCharacter.fWeaponStats_MHDPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "MHAPS":
                                                oCharacter.fWeaponStats_MHAPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "Dualwield":
                                                if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) {
                                                    if (oAttributes[k].Value.ToLower() == "false") { ((ClassObjects.ocBarbarian)oCharacter).bWeaponStat_Dualwield = false; }
                                                    else { ((ClassObjects.ocBarbarian)oCharacter).bWeaponStat_Dualwield = true; }
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) {
                                                    if (oAttributes[k].Value.ToLower() == "false") { ((ClassObjects.ocDemonHunter)oCharacter).bWeaponStat_Dualwield = false; }
                                                    else { ((ClassObjects.ocDemonHunter)oCharacter).bWeaponStat_Dualwield = true; }
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk) {
                                                    if (oAttributes[k].Value.ToLower() == "false") { ((ClassObjects.ocMonk)oCharacter).bWeaponStat_Dualwield = false; }
                                                    else { ((ClassObjects.ocMonk)oCharacter).bWeaponStat_Dualwield = true; }
                                                }
                                                else {
                                                    bTemp = false;
                                                    sError = "WeaponStats: Dualwield: " + oCharacter.eClass.ToString();
                                                }
                                                break;
                                            case "OHDPS":
                                                if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) {
                                                    ((ClassObjects.ocBarbarian)oCharacter).fWeaponStats_OHDPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) {
                                                    ((ClassObjects.ocDemonHunter)oCharacter).fWeaponStats_OHDPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk) {
                                                    ((ClassObjects.ocMonk)oCharacter).fWeaponStats_OHDPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else {
                                                    bTemp = false;
                                                    sError = "WeaponStats: OHDPS: " + oCharacter.eClass.ToString();
                                                }
                                                break;
                                            case "OHAPS":
                                                if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) {
                                                    ((ClassObjects.ocBarbarian)oCharacter).fWeaponStats_OHAPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) {
                                                    ((ClassObjects.ocDemonHunter)oCharacter).fWeaponStats_OHAPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk) {
                                                    ((ClassObjects.ocMonk)oCharacter).fWeaponStats_OHAPS = float.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                }
                                                else {
                                                    bTemp = false;
                                                    sError = "WeaponStats: OHAPS: " + oCharacter.eClass.ToString();
                                                }
                                                break;
                                            default:
                                                bTemp = false;
                                                break;
                                        }
                                    }
                                    break;
                                case "OtherStats":
                                    oAttributes = oNodes_Childs[j].Attributes;
                                    for (int k = 0; k < oAttributes.Count; k++) {
                                        switch (oAttributes[k].Name) {
                                            case "PhysicalBonus":
                                                oCharacter.iOtherStat_PhysicalBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "ArcaneBonus":
                                                oCharacter.iOtherStat_ArcaneBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "ColdBonus":
                                                oCharacter.iOtherStat_ColdBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "FireBonus":
                                                oCharacter.iOtherStat_FireBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "HolyBonus":
                                                oCharacter.iOtherStat_HolyBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "LighteningBonus":
                                                oCharacter.iOtherStat_LighteningBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            case "PoisonBonus":
                                                oCharacter.iOtherStat_PoisonBonus = int.Parse(oAttributes[k].Value, CultureInfo.InvariantCulture);
                                                break;
                                            default:
                                                bTemp = false;
                                                break;
                                        }
                                    }
                                    break;
                                case "ActiveAbilities":

                                    break;
                                case "PassiveAbilities":

                                    break;
                                case "ClassStats":

                                    break;
                                default:

                                    break;
                            }
                        }
                        if (bTemp) {
                            oReader.Close();
                            sTemp = get_FreeCharacterID();

                            if (sTemp != null) {
                                oCharacter.sID = sTemp;
                                lCharacters.Add(oCharacter);
                                iLoadCount++;
                            }
                            else {
                                System.Windows.MessageBox.Show("Well, this is awkward.\nSeems like no free Character-IDs are available.\n\nLoading of characters stopped.", "D3crft", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                                return iLoadCount;
                            }

                        }
                    }
                    if (!bTemp) {
                        oReader.Close();
                        System.Windows.MessageBox.Show("Uh, snap!\nThis character file is not formated the right way:\n" + sFiles[i] + "\n\n" + sError, "D3crft", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                    evCharacterLoadingProcess_PostloadUpdate(iTotalCharCount, iLoadCount, sFiles[i]);
                }
            }

            evCharacterLoadingProcess_Finished(iTotalCharCount, iTotalCharCount, "character(s)");
            return 0;
        }

        private int do_SaveCharacters(string sPath) {
            for (int i = 0; i < lCharacters.Count; i++) {
                do_SaveCharacter(sPath, lCharacters[i]);
            }
            return 0;
        }

        private bool do_SaveCharacter(string sPath, ClassObjects.ocCharacter oCharacter) {
            FileInfo oFInfo;
            XmlElement oElement_Character, oElement_Temp;
            string sFile;

            sFile = sPath + "\\" + oCharacter.sName + ".xml";
            oFInfo = new FileInfo(sFile);
            if (oFInfo.Exists) { oFInfo.Delete(); }

            XmlDocument oDoc = new XmlDocument();

            oElement_Character = oDoc.CreateElement("Character");
            oElement_Character.SetAttribute("Name", oCharacter.sName);
            oElement_Character.SetAttribute("Class", oCharacter.eClass.ToString());
            oDoc.AppendChild(oElement_Character);

            oElement_Temp = oDoc.CreateElement("BaseStats");
            oElement_Temp.SetAttribute("Strength", oCharacter.iBaseStat_Strength.ToString());
            oElement_Temp.SetAttribute("Dexterity", oCharacter.iBaseStat_Dexterity.ToString());
            oElement_Temp.SetAttribute("Intelligence", oCharacter.iBaseStat_Intelligence.ToString());
            oElement_Temp.SetAttribute("Vitality", oCharacter.iBaseStat_Vitality.ToString());
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("OffensiveStats");
            oElement_Temp.SetAttribute("AttackSpeedIncrease", oCharacter.fOffStat_AttackSpeedInrease.ToString(CultureInfo.InvariantCulture));
            oElement_Temp.SetAttribute("CritChance", oCharacter.fOffStat_CritChance.ToString(CultureInfo.InvariantCulture));
            oElement_Temp.SetAttribute("CritDamage", oCharacter.fOffStat_CritDamage.ToString(CultureInfo.InvariantCulture));
            oElement_Temp.SetAttribute("BonusDamageMin", oCharacter.iOffStat_BonusDamage_Min.ToString());
            oElement_Temp.SetAttribute("BonusDamageMax", oCharacter.iOffStat_BonusDamage_Max.ToString());
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("WeaponStats");
            oElement_Temp.SetAttribute("MHDPS", oCharacter.fWeaponStats_MHDPS.ToString(CultureInfo.InvariantCulture));
            oElement_Temp.SetAttribute("MHAPS", oCharacter.fWeaponStats_MHAPS.ToString(CultureInfo.InvariantCulture));
            if ((oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) || (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) || (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk)) {
                if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) {
                    oElement_Temp.SetAttribute("Dualwield", ((ClassObjects.ocBarbarian)oCharacter).bWeaponStat_Dualwield.ToString());
                    oElement_Temp.SetAttribute("OHDPS", ((ClassObjects.ocBarbarian)oCharacter).fWeaponStats_OHDPS.ToString(CultureInfo.InvariantCulture));
                    oElement_Temp.SetAttribute("OHAPS", ((ClassObjects.ocBarbarian)oCharacter).fWeaponStats_OHAPS.ToString(CultureInfo.InvariantCulture));
                }
                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) {
                    oElement_Temp.SetAttribute("Dualwield", ((ClassObjects.ocDemonHunter)oCharacter).bWeaponStat_Dualwield.ToString());
                    oElement_Temp.SetAttribute("OHDPS", ((ClassObjects.ocDemonHunter)oCharacter).fWeaponStats_OHDPS.ToString(CultureInfo.InvariantCulture));
                    oElement_Temp.SetAttribute("OHAPS", ((ClassObjects.ocDemonHunter)oCharacter).fWeaponStats_OHAPS.ToString(CultureInfo.InvariantCulture));
                }
                else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk) {
                    oElement_Temp.SetAttribute("Dualwield", ((ClassObjects.ocMonk)oCharacter).bWeaponStat_Dualwield.ToString());
                    oElement_Temp.SetAttribute("OHDPS", ((ClassObjects.ocMonk)oCharacter).fWeaponStats_OHDPS.ToString(CultureInfo.InvariantCulture));
                    oElement_Temp.SetAttribute("OHAPS", ((ClassObjects.ocMonk)oCharacter).fWeaponStats_OHAPS.ToString(CultureInfo.InvariantCulture));
                }

            }
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("OtherStats");
            oElement_Temp.SetAttribute("PhysicalBonus", oCharacter.iOtherStat_PhysicalBonus.ToString());
            oElement_Temp.SetAttribute("ArcaneBonus", oCharacter.iOtherStat_ArcaneBonus.ToString());
            oElement_Temp.SetAttribute("ColdBonus", oCharacter.iOtherStat_ColdBonus.ToString());
            oElement_Temp.SetAttribute("FireBonus", oCharacter.iOtherStat_FireBonus.ToString());
            oElement_Temp.SetAttribute("HolyBonus", oCharacter.iOtherStat_HolyBonus.ToString());
            oElement_Temp.SetAttribute("LighteningBonus", oCharacter.iOtherStat_LighteningBonus.ToString());
            oElement_Temp.SetAttribute("PoisonBonus", oCharacter.iOtherStat_PoisonBonus.ToString());
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("ActiveAbilities");
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[0]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[1]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[2]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[3]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[4]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iActiveSkills[5]));
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("PassiveAbilities");
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iPassiveSkills[0]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iPassiveSkills[1]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iPassiveSkills[2]));
            oElement_Temp.AppendChild(oDoc.CreateTextNode("#" + oCharacter.iPassiveSkills[3]));
            oElement_Character.AppendChild(oElement_Temp);

            oElement_Temp = oDoc.CreateElement("ClassStats");
            if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Barbarian) {
                oElement_Temp.SetAttribute("BattleRage", ((ClassObjects.ocBarbarian)oCharacter).bBattleRageActive.ToString());
                oElement_Temp.SetAttribute("Frenzy", ((ClassObjects.ocBarbarian)oCharacter).bFrencyActive.ToString());
                oElement_Temp.SetAttribute("Rampage", ((ClassObjects.ocBarbarian)oCharacter).bRampageActive.ToString());
                oElement_Temp.SetAttribute("WOTB", ((ClassObjects.ocBarbarian)oCharacter).bWillOfTheBerserkerActive.ToString());
            }
            else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Crusader) {
                oElement_Temp.SetAttribute("C1", false.ToString());
                oElement_Temp.SetAttribute("C2", false.ToString());
                oElement_Temp.SetAttribute("C3", false.ToString());
                oElement_Temp.SetAttribute("C4", false.ToString());
            }
            else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter) {
                oElement_Temp.SetAttribute("DH1", false.ToString());
                oElement_Temp.SetAttribute("DH2", false.ToString());
                oElement_Temp.SetAttribute("DH3", false.ToString());
                oElement_Temp.SetAttribute("DH4", false.ToString());
            }
            else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Monk) {
                oElement_Temp.SetAttribute("M1", false.ToString());
                oElement_Temp.SetAttribute("M2", false.ToString());
                oElement_Temp.SetAttribute("M3", false.ToString());
                oElement_Temp.SetAttribute("M4", false.ToString());
            }
            else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Wizard) {
                oElement_Temp.SetAttribute("W1", false.ToString());
                oElement_Temp.SetAttribute("W2", false.ToString());
                oElement_Temp.SetAttribute("W3", false.ToString());
                oElement_Temp.SetAttribute("W4", false.ToString());
            }
            else if (oCharacter.eClass == ClassObjects.ocCharacter.eCharacterClass.Witch_Doctor) {
                oElement_Temp.SetAttribute("WD1", false.ToString());
                oElement_Temp.SetAttribute("WD2", false.ToString());
                oElement_Temp.SetAttribute("WD3", false.ToString());
                oElement_Temp.SetAttribute("WD4", false.ToString());
            }
            oElement_Character.AppendChild(oElement_Temp);

            oDoc.Save(sFile);
            return true;
        }

        #endregion

        // ####################################################
        // #####    Events
        // ####################################################
        #region Events

        private void ev_Object_CharacterLoadingProcess_Started(int iTotalCharCount, int iCurrentCharCount, string sFilename) {

        }

        private void ev_Object_CharacterLoadingProcess_PreloadUpdate(int iTotalCharCount, int iCurrentCharCount, string sFilename) {

        }

        private void ev_Object_CharacterLoadingProcess_PostloadUpdate(int iTotalCharCount, int iCurrentCharCount, string sFilename) {

        }

        private void ev_Object_CharacterLoadingProcess_Finished(int iTotalCharCount, int iCurrentCharCount, string sFilename) {

        }

        #endregion
    }
}
